package com.agileai.esb.smc.controller.monitor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;

import com.agileai.domain.DataParam;
import com.agileai.domain.DataRow;
import com.agileai.esb.smc.bizmoduler.analysis.WebServiceStatManage;
import com.agileai.esb.smc.bizmoduler.sysres.SysUserManage;
import com.agileai.esb.smc.domain.User;
import com.agileai.esb.wsmodel.WSRuntimeAnalysis;
import com.agileai.esb.wsmodel.WSRuntimeStat;
import com.agileai.hotweb.annotation.PageAction;
import com.agileai.hotweb.common.BeanFactory;
import com.agileai.hotweb.controller.core.BaseHandler;
import com.agileai.hotweb.domain.FormSelect;
import com.agileai.hotweb.renders.AjaxRenderer;
import com.agileai.hotweb.renders.LocalRenderer;
import com.agileai.hotweb.renders.ViewRenderer;
import com.agileai.util.StringUtil;

public class WSRuntimeStatListHandler
        extends BaseHandler {
	
    public WSRuntimeStatListHandler() {
        super();
    }

	public ViewRenderer prepareDisplay(DataParam param){
		WebServiceStatManage service = lookupService(WebServiceStatManage.class);
		
		List<DataRow> appRecords = service.findAppRecords();
		User user = (User) this.getUser();
		if(!user.isAdmin()){
			SysUserManage userManage = this.lookupService(SysUserManage.class);
			String userId = user.getId();
			HashMap<String,DataRow> userAuthRecords = userManage.findAuthAppMap(userId);
			List<DataRow> results = new ArrayList<DataRow>();
			for (int i = 0; i < appRecords.size(); i++) {
				DataRow appRecord = appRecords.get(i);
				String appName = appRecord.getString("APP_NAME");
				if (userAuthRecords.containsKey(appName)){
					results.add(appRecord);
				}
			}
			appRecords = results;
		}
		FormSelect appNameSelect = new FormSelect();
		appNameSelect.setKeyColumnName("APP_NAME");
		appNameSelect.setValueColumnName("APP_NAME");
		appNameSelect.putValues(appRecords);
		String appSelect = param.get("appName");
		
		if(StringUtil.isNotNullNotEmpty(param.get("appName"))){
			appNameSelect.setSelectedValue(appSelect);
		}
		
		param.put("appName", appNameSelect);
		this.setAttribute("appName",appNameSelect);	
		
		String serviceCode = param.getString("serCode");		
		if(StringUtil.isNotNullNotEmpty(serviceCode)){
			this.setAttribute("serCode",serviceCode);	
		}	
		this.setAttributes(param);
		processPageAttributes(param);
		return new LocalRenderer(getPage());
	}    
	
    protected void processPageAttributes(DataParam param) {

    }
    
	@PageAction
	public ViewRenderer query(DataParam param){
		return prepareDisplay(param);
	}
    
    @PageAction
    public ViewRenderer loadMonitorData(DataParam param){
    	int page = param.getInt("page");
		int rows = param.getInt("rows");
    	String responseText =null;
    	try {
    		WSRuntimeStat[] runtimeStats = WSRuntimeAnalysis.geInstance(false).getRuntimeStats();
    		List<WSRuntimeStat> runtimeStatList = this.filterRuntimeStat(runtimeStats, param);
    		responseText = buildJsonText(page,rows,runtimeStatList);
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
		}
    	return new AjaxRenderer(responseText);
    }

    private List<WSRuntimeStat> filterRuntimeStat(WSRuntimeStat[] runtimeStats,DataParam param){
    	List<WSRuntimeStat> result = new ArrayList<WSRuntimeStat>();
		String serviceCode = param.getString("serCode");
    	String appName = param.getString("appName");
    	if(StringUtil.isNotNullNotEmpty(appName)){
    		//not use privile filter
    		if (StringUtil.isNotNullNotEmpty(serviceCode)){
    			for(int i=0;i < runtimeStats.length;i++){
    				WSRuntimeStat runtimeStat = runtimeStats[i];
    				String tempAppName = runtimeStat.getAppName();
    				if (tempAppName.equals(appName)){
    					String serviceName = runtimeStat.getServiceName();
    					if (serviceCode.equals(serviceName)){
    						result.add(runtimeStat);
    					}
    				}
    			}
    			
    		}else{
    			for(int i=0;i < runtimeStats.length;i++){
    				WSRuntimeStat runtimeStat = runtimeStats[i];
    				String key = runtimeStat.getAppName();
    				if (key.equals(appName)){
    					result.add(runtimeStat);
    				}
    			}
    		}
    	}
    	else{
    		//use privilege filter
    		User user = (User) this.getUser();
    		if(!user.isAdmin()){
    			SysUserManage userManage = this.lookupService(SysUserManage.class);
    			String userId = user.getId();
    			HashMap<String,DataRow> userAuthRecords = userManage.findAuthAppMap(userId);
        		if (StringUtil.isNotNullNotEmpty(serviceCode)){
        			for(int i=0;i < runtimeStats.length;i++){
        				WSRuntimeStat runtimeStat = runtimeStats[i];
    					String tempAppName = runtimeStat.getAppName();
    					String serviceName = runtimeStat.getServiceName();
    					if (serviceCode.equals(serviceName) && userAuthRecords != null && userAuthRecords.containsKey(tempAppName)){
    						result.add(runtimeStat);
    					}
        			}
        		}
        		else{
        			for(int i=0;i < runtimeStats.length;i++){
        				WSRuntimeStat runtimeStat = runtimeStats[i];
    					String tempAppName = runtimeStat.getAppName();
    					if (userAuthRecords != null && userAuthRecords.containsKey(tempAppName)){
    						result.add(runtimeStat);
    					}
        			}
        		}
    		}
    		else{
        		if (StringUtil.isNotNullNotEmpty(serviceCode)){
        			for(int i=0;i < runtimeStats.length;i++){
        				WSRuntimeStat runtimeStat = runtimeStats[i];
    					String serviceName = runtimeStat.getServiceName();
    					if (serviceCode.equals(serviceName)){
    						result.add(runtimeStat);
    					}
        			}
        		}else{
        			for(int i=0;i < runtimeStats.length;i++){
        				WSRuntimeStat runtimeStat = runtimeStats[i];
    					result.add(runtimeStat);
        			}
        		}
    		}
    	}
    	
    	return result;
    }
    
    @PageAction
    public ViewRenderer resetMonitor(DataParam param){
    	String responseText = FAIL;
    	try {
    		WebServiceStatManage webServiceStatManage = (WebServiceStatManage) BeanFactory.instance().getBean("webServiceStatManageService");
    		ConcurrentHashMap<String,WSRuntimeStat> runtimeStats = WSRuntimeAnalysis.geInstance(true).getTransitRuntimeStatMap();
    		webServiceStatManage.insertStatRecords(runtimeStats);
    		responseText = SUCCESS;			
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(),e);
		}
    	return new AjaxRenderer(responseText);
    }    
    
    private String buildJsonText(int page,int rows,List<WSRuntimeStat> runtimeStatList){
    	String result = null;
    	try {
        	JSONArray jsonArray = new JSONArray();
        	JSONObject json = new JSONObject();
        	int start = (page - 1) * rows;
        	int end = start + rows;
        	if(runtimeStatList.size() < end){
        		end = runtimeStatList.size();
        	}
    		for (int i= start;i < end;i++){
        		WSRuntimeStat runtimeStat = runtimeStatList.get(i);
        		JSONObject jsonObject = new JSONObject();
        		jsonObject.put("statId",runtimeStat.getStatId());
        		jsonObject.put("appName",runtimeStat.getAppName());
        		jsonObject.put("serviceId",runtimeStat.getServiceId());
        		jsonObject.put("serviceName",runtimeStat.getServiceName());
        		jsonObject.put("serviceAlias",runtimeStat.getServiceAlias());
        		jsonObject.put("serviceOperation",runtimeStat.getOperationName());
        		jsonObject.put("serviceType",runtimeStat.getServiceType());
        		jsonObject.put("totalCount",runtimeStat.getTotalCount());
        		jsonObject.put("successCount",runtimeStat.getSuccessCount());
        		jsonObject.put("failureCount",runtimeStat.getFailureCount());
        		jsonObject.put("maxRuntime",runtimeStat.getMaxRuntime());
        		jsonObject.put("minRuntime",runtimeStat.getMinRuntime());
        		jsonObject.put("averageRuntime",runtimeStat.getTotalRuntime()/runtimeStat.getTotalCount());
        		jsonArray.put(jsonObject);
        	}
    		json.put("rows", jsonArray);
	        json.put("total", runtimeStatList.size());
        	result = json.toString();
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
		}
    	return result;
    }
    
    protected void initParameters(DataParam param) {

    }
}